package com.zslibrary.Parse;

import com.zslibrary.Enum.BoardId;
import com.zslibrary.Enum.NFCMessageId;
import com.zslibrary.Enum.Protocol;
import com.zslibrary.Structure.MessageStruct;
import com.zslibrary.Structure.ReplyStruct;
import com.zslibrary.Structure.RequestStruct;
import com.zslibrary.Tools.FrameBuilder;
import com.zslibrary.Tools.ZSLog;

import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

public class ParseMessage {
    private byte mControlCode=0;

    public ReplyStruct parseReceiveData(byte boardId,byte[] receiveData,Boolean isSync){
        if(receiveData==null||receiveData.length==0){
            return null;
        }
        FrameBuilder builder=new FrameBuilder(receiveData);
        try{
            byte XOR=builder.getXOR();
            short returnCodes=(short)builder.popData(2);
            short dataLen=(short)builder.popData(2);
            if(dataLen==(receiveData.length-5)&&(XOR==0)){
                ReplyStruct reply=new ReplyStruct();
                reply.dataLength=dataLen;
                reply.returnCode=returnCodes;
//            reply.messageSize=0;
                if(dataLen==0){ /*数据长度为0*/
                    reply.messages=new MessageStruct[0];
                    return reply;
                }
                List<MessageStruct> messageList=new ArrayList<>();
                byte[] buffer=builder.popBytes(dataLen);
                if(isSync){
                    MessageStruct msg=new MessageStruct();
                    msg.messageData=buffer;
                    msg.messageLength=buffer.length;
                    reply.messages=new MessageStruct[1];
                    reply.messages[0]=msg;
                    return reply;
                }else {
                    FrameBuilder msgBuilder = new FrameBuilder(buffer);
                    while (msgBuilder.length() > 0) {
                        MessageStruct message;
                        short messageId = (short) msgBuilder.popData(2);
                        message = this.parseAsyncMessage(boardId, messageId, msgBuilder);
                        if (message != null) {
                            messageList.add(message);
                        } else {
                            reply = null;
                            break;
                        }
                    }
                    if (reply != null) {
                        reply.messages = messageList.toArray(new MessageStruct[messageList.size()]);
                        return reply;
                    }
                }
            }
        }catch(Exception e){
            //e.printStackTrace();
            ZSLog.e(e.toString());
        }

        return null;
    }

    public FrameBuilder PackSendData(RequestStruct busData){
        FrameBuilder sendFrame=new FrameBuilder(2048);
        byte control_code=this.generateControl();
        byte XOR;
        //TODO:判断数据的有效性
        sendFrame.append(busData.boardId);
        sendFrame.append(control_code);
        sendFrame.append(busData.gRequest.requstId);
        sendFrame.append(busData.gRequest.dataLength);
        sendFrame.append(busData.gRequest.data);
        XOR=sendFrame.getXOR();
        sendFrame.append(XOR);
        return sendFrame;
    }

    private byte generateControl(){
        byte ret=(byte)(((mControlCode&0xF)<<4)|7);
        mControlCode++;
        return ret;
    }

    private MessageStruct parseAsyncMessage(byte boardId,short messageId,FrameBuilder builder){
        MessageStruct message=new MessageStruct();
        if(boardId== BoardId.IO_BOARD){
            switch(messageId){
                case Protocol.MSG_REPORT_BEGIN:{
                    message.messageLength=2;
                    message.messageId= Protocol.MSG_REPORT_BEGIN;
                    message.messageData=builder.popBytes(2);
                    if(message.messageData==null){
                        message=null;
                        break;
                    }
                }break;

                case Protocol.MSG_REPORT_END:{
                    message.messageId= Protocol.MSG_REPORT_END;
                    message.messageLength=4;
                    message.messageData=builder.popBytes(4);
                    if(message.messageData==null) {
                        message = null;
                        break;
                    }

                }break;

                case Protocol.MSG_BOARD_STATUS:{
                    message.messageId= Protocol.MSG_BOARD_STATUS;
                    message.messageLength=4;
                    message.messageData=builder.popBytes(4);
                    if(message.messageData==null) {
                        message = null;
                        break;
                    }
                }break;

                case Protocol.MSG_BOARD_RESET:{
                    message.messageId= Protocol.MSG_BOARD_RESET;
                    message.messageLength=0;
                    message.messageData=null;
                }break;

                case Protocol.MSG_SET_COMP_ERR:{
                    message.messageId= Protocol.MSG_SET_COMP_ERR;
                    message.messageLength=(short)builder.popData(2)+2+1+1;
                    message.messageData=builder.popBytes(message.messageLength);
                    if(message.messageData==null) {
                        message = null;
                        break;
                    }
                }break;

                case Protocol.MSG_CLEAR_COMP_ERR:{
                    message.messageId= Protocol.MSG_CLEAR_COMP_ERR;
                    message.messageLength=(short)builder.popData(2)+2;
                    message.messageData=builder.popBytes(message.messageLength);
                    if(message.messageData==null) {
                        message = null;
                        break;
                    }
                }break;

                case Protocol.MSG_REPLY_GATE_STATUS:{
                    message.messageId=Protocol.MSG_REPLY_GATE_STATUS;
                    message.messageLength=(short)builder.popData(2)*5+2;
                    message.messageData=builder.popBytes(message.messageLength);
                    if(message.messageData==null) {
                        message = null;
                        break;
                    }
                }break;

                case Protocol.MSG_PRODUCT_ON_PROGRESS:{
                    message.messageId= Protocol.MSG_PRODUCT_ON_PROGRESS;
                    message.messageLength=4;
                    message.messageData=builder.popBytes(4);
                    if(message.messageData==null) {
                        message = null;
                        break;
                    }
                }break;

                case Protocol.MSG_PRODUCT_SHOW_MSG:{
                    message.messageId= Protocol.MSG_PRODUCT_SHOW_MSG;
                    message.messageLength=4;
                    message.messageData=builder.popBytes(4);
                    if(message.messageData==null) {
                        message = null;
                        break;
                    }
                }break;

                case Protocol.MSG_PRODUCT_DONE:{
                    message.messageId= Protocol.MSG_PRODUCT_DONE;
                    message.messageLength=2;
                    message.messageData=builder.popBytes(2);
                    if(message.messageData==null) {
                        message = null;
                        break;
                    }
                }break;

                case Protocol.MSG_REPORT_STR:{
                    builder.popData(1);
                    message.messageId= Protocol.MSG_REPORT_STR;
                    message.messageLength=builder.popData(2);
                    message.messageData=builder.popBytes(message.messageLength);
                    if(message.messageData==null) {
                        message = null;
                        break;
                    }
                }break;

                case Protocol.MSG_GET_SENSOR_VALUE:{
                    message.messageId= Protocol.MSG_GET_SENSOR_VALUE;
                    message.messageLength=8;
                    message.messageData=builder.popBytes(8);
                    if(message.messageData==null) {
                        message = null;
                        break;
                    }
                }break;

                case Protocol.MSG_GET_TEST_INFOS:{

                }break;

                case Protocol.MSG_REQUIRE_KEYS:{
                    builder.popBytes(1);
                }break;

                default:
                    break;
            }
        }else if(boardId==BoardId.NFC_BOARD){
            message.messageId= NFCMessageId.MSG_DETECTED_CARD;
            message.messageLength=8;
            message.messageData=builder.popBytes(8);
            if(message.messageData==null) {
                message = null;
            }
        }
        return message;
    }
}
